Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: datetime for defaultLocale set fa #238

Merged

Conversation

datamweb
Copy link
Collaborator

@datamweb datamweb commented Jun 12, 2022

When toDateTimeString() is used. If defaultLocale = 'fa'.
The value of the datetime will be UTF-8 string (33) "۲۰۲۲-۰۶-۱۲ ۲۲:۳۰:۳۵".
In this case, the database enters the information as 0000-00-00 00:0:00.
Which causes a bug in the shield.
In this PR I tried to solve this problem.

note: This method can also solve the problem. $time = new Time('now','','en-US')

Data of Table "auth_groups_users":

+----+---------+-------+--------------------+
| id | user_id | group | created_at         |
+----+---------+-------+--------------------+
| 7  | 7       | user  | 0000-00-00 00:0... |
| 22 | 22      | user  | 0000-00-00 00:0... |
| 23 | 23      | user  | 2022-06-12 19:3... |
+----+---------+-------+--------------------+

@datamweb
Copy link
Collaborator Author

@kenjis I'm not sure this is the best solution, please review.
I will also send the test after confirmation.

@kenjis kenjis added the bug Something isn't working label Jun 12, 2022
@kenjis
Copy link
Member

kenjis commented Jun 12, 2022

toDateTimeString() returns localized datetime string. So it is not appropriate.

Your solution is good.

@datamweb datamweb marked this pull request as draft June 13, 2022 01:55
@datamweb datamweb changed the title fix: datatime for defaultLocale set fa fix: datetime for defaultLocale set fa Jun 13, 2022
@datamweb datamweb force-pushed the fix-datatime-if-defaultLocale-fa branch from e6f7014 to 70e81cc Compare June 13, 2022 05:58
@datamweb
Copy link
Collaborator Author

I tried to put the test in the appropriate file. Adding this test to other files(AccessTokens.php , MagicLinkController.php ...) seems to cause bloating.
However please let me know if you need to change.

@datamweb datamweb marked this pull request as ready for review June 13, 2022 07:10
Co-authored-by: kenjis <kenji.uui@gmail.com>
$this->dontSeeInDatabase('auth_groups_users', [
'user_id' => $this->user->id,
'group' => 'admin',
'created_at' => '0000-00-00 00:00:00',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't '0000-00-00 00:00:00' MySQL specific?

Does this test fail before applying your fixes?

Comment on lines 308 to 312
$this->hasInDatabase('auth_groups_users', [
'user_id' => $this->user->id,
'group' => 'admin',
'created_at' => Time::now()->format('Y-m-d H:i:s'),
]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hasInDatabase() inserts a record:
https://codeigniter4.github.io/CodeIgniter4/testing/database.html?highlight=hasindatabase#hasindatabase-table-data
Why do you need to insert the data here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, I was just trying to check the correct record of the date in the database.
That's why I used it.

Copy link
Member

@kenjis kenjis Jun 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test does not check anything.

Because hasInDatabase() inserts a record.
So the admin record for the user exists.
So $this->user->addGroup('admin') does not insert a record.

After all, you insert a record by hasInDatabase() and check it by dontSeeInDatabase().
You don't check any product code behavior.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh my God.
This is a ridiculous mistake, I'm sorry.
Thanks for the explanation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not your fault @datamweb, I have always felt that hasInDatabse() was very poorly named.

@kenjis
Copy link
Member

kenjis commented Jun 13, 2022

@datamweb The following test should work, but it does not work because of CI4 Time bug. codeigniter4/CodeIgniter4#6116

    public function testCreatedAtIfDefaultLocaleSetFaWithAddGroup(): void
    {
        $currentLocale = Locale::getDefault();
        Locale::setDefault('fa');

        Time::setTestNow('March 10, 2017', 'America/Chicago');

        $this->user->addGroup('admin');

        $this->seeInDatabase('auth_groups_users', [
            'user_id'    => $this->user->id,
            'group'      => 'admin',
            'created_at' => '2017-03-10 00:00:00',
        ]);

        Locale::setDefault($currentLocale);
    }

@datamweb
Copy link
Collaborator Author

    public function testCreatedAtIfDefaultLocaleSetFaWithAddGroup(): void
    {
        $currentLocale = Locale::getDefault();
        Locale::setDefault('fa');

        Time::setTestNow('March 10, 2017', 'America/Chicago');

        $this->user->addGroup('admin');

        $this->seeInDatabase('auth_groups_users', [
            'user_id'    => $this->user->id,
            'group'      => 'admin',
            'created_at' => '2017-03-10 00:00:00',
        ]);

        Locale::setDefault($currentLocale);
    }

@kenjis, So should I replace the test?

@MGatner
Copy link
Member

MGatner commented Jun 13, 2022

Let's hold off on this until we resolve the issue with the framework. The User Guide seems strongly in favor of toDateTimeString() for database inserts, so this might be the correct code and the bug is actually that the framework is localizing the result.

@datamweb
Copy link
Collaborator Author

datamweb commented Jun 13, 2022

Let's hold off on this until we resolve the issue with the framework. The User Guide seems strongly in favor of toDateTimeString() for database inserts, so this might be the correct code and the bug is actually that the framework is localizing the result.

Okay. Please let me know if need to do something.

@kenjis
Copy link
Member

kenjis commented Jun 15, 2022

@MGatner The bug in the framework was fixed in the develop, but we can't use it in this repository until it is released.
What do we do?

@MGatner
Copy link
Member

MGatner commented Jun 15, 2022

This PR is still good, it is just the test case that needs the framework change, correct? Since the test case is covering an external bug I don't think it is necessary - we can proceed with the content change. If you want to leave the test in place with a conditional skip it could check the framework version on CodeIgniter\CodeIgniter.

@MGatner
Copy link
Member

MGatner commented Jun 15, 2022

... Alternatively I can make the bugfix release of 4.2.1 today and we can use that.

@kenjis
Copy link
Member

kenjis commented Jun 15, 2022

Yes, the product code seems okay, but test code is now broken.
And if we write correct test, we hit the framework bug.

If you release 4.2.1, it might be better to revert codeigniter4/CodeIgniter4#5653
See codeigniter4/CodeIgniter4#6086 (comment)

@kenjis
Copy link
Member

kenjis commented Jun 16, 2022

@datamweb Update the test, and let's move on.

--- a/tests/Authorization/AuthorizableTest.php
+++ b/tests/Authorization/AuthorizableTest.php
@@ -2,6 +2,7 @@
 
 namespace Tests\Authorization;
 
+use CodeIgniter\CodeIgniter;
 use CodeIgniter\I18n\Time;
 use CodeIgniter\Shield\Authorization\AuthorizationException;
 use CodeIgniter\Shield\Models\UserModel;
@@ -302,22 +303,23 @@ public function testCanCascadesToGroupsWithWildcards(): void
      */
     public function testCreatedAtIfDefaultLocaleSetFaWithAddGroup(): void
     {
+        if (version_compare(CodeIgniter::CI_VERSION, '4.2.1', '<')) {
+            $this->markTestSkipped('This test does not work on CI v4.2.0 or before due to a bug.');
+        }
+
         $currentLocale = Locale::getDefault();
         Locale::setDefault('fa');
 
-        $this->hasInDatabase('auth_groups_users', [
-            'user_id'    => $this->user->id,
-            'group'      => 'admin',
-            'created_at' => Time::now()->format('Y-m-d H:i:s'),
-        ]);
+        Time::setTestNow('March 10, 2017', 'America/Chicago');
 
         $this->user->addGroup('admin');
 
-        $this->dontSeeInDatabase('auth_groups_users', [
+        $this->seeInDatabase('auth_groups_users', [
             'user_id'    => $this->user->id,
             'group'      => 'admin',
-            'created_at' => '0000-00-00 00:00:00',
+            'created_at' => '2017-03-10 00:00:00',
         ]);
+
         Locale::setDefault($currentLocale);
     }
 }

Copy link
Member

@MGatner MGatner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PHPStan doesn't like the constant being variable. I don't think this will fix Rector though, we probably need to add a skip for it.

I will try to release 4.2.1 this morning so maybe we can ignore all this.

tests/Authorization/AuthorizableTest.php Outdated Show resolved Hide resolved
Co-authored-by: MGatner <mgatner@icloud.com>
@kenjis
Copy link
Member

kenjis commented Jun 16, 2022

--- a/rector.php
+++ b/rector.php
@@ -20,6 +20,7 @@
 use Rector\Config\RectorConfig;
 use Rector\Core\ValueObject\PhpVersion;
 use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPromotedPropertyRector;
+use Rector\DeadCode\Rector\If_\UnwrapFutureCompatibleIfPhpVersionRector;
 use Rector\DeadCode\Rector\MethodCall\RemoveEmptyMethodCallRector;
 use Rector\DeadCode\Rector\StmtsAwareInterface\RemoveJustPropertyFetchForAssignRector;
 use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector;
@@ -80,6 +81,11 @@
             __DIR__ . '/tests',
         ],
 
+        // check on constant compare
+        UnwrapFutureCompatibleIfPhpVersionRector::class => [
+            __DIR__ . '/tests/Authorization/AuthorizableTest.php',
+        ],
+
         // Ignore files that should not be namespaced to their folder
         NormalizeNamespaceByPSR4ComposerAutoloadRector::class => [
             __DIR__ . '/src/Helpers',
diff --git a/tests/Authorization/AuthorizableTest.php b/tests/Authorization/AuthorizableTest.php
index 3667f7c..0a8ea43 100644
--- a/tests/Authorization/AuthorizableTest.php
+++ b/tests/Authorization/AuthorizableTest.php
@@ -308,6 +308,7 @@ public function testCreatedAtIfDefaultLocaleSetFaWithAddGroup(): void
             $this->markTestSkipped('This test does not work on CI v4.2.0 or before due to a bug.');
         }
 
+        // @phpstan-ignore-next-line
         $currentLocale = Locale::getDefault();
         Locale::setDefault('fa');
 

@MGatner
Copy link
Member

MGatner commented Jun 16, 2022

4.2.1 is out, safe to roll back these workarounds

@kenjis
Copy link
Member

kenjis commented Jun 26, 2022

@datamweb Removing the if in the test case is one last job for this PR.
Can you?

@datamweb
Copy link
Collaborator Author

Hi @kenjis , I'm sorry for the delay. I was busy these few days.
Thanks for the review.

@kenjis kenjis merged commit 0dd0562 into codeigniter4:develop Jun 28, 2022
@kenjis
Copy link
Member

kenjis commented Jun 28, 2022

Okay, all green!
Merged.

@datamweb datamweb deleted the fix-datatime-if-defaultLocale-fa branch June 28, 2022 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants